#include "escape.h"
/* vim:ts=4:sw=4:noet
 * (tabspace=4)
 * 
 * Copyright (C) 2004, 2005 Walter Doekes, <walter@djcvt.net>.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "texts.h"
#include <stdio.h>

void strtoctrlesc(unsigned char* dest, unsigned const char* src) {
	while(*src != '\0') {
		if(0) { /* the optimizer will take care of this */
#define ELIF(ctrl, ch) } else if(*src == ctrl) { *dest++ = '\\'; *dest++ = ch
		ELIF('\a', 'a');
		ELIF('\b', 'b');
		ELIF('\t', 't');
		ELIF('\n', 'n');
		ELIF('\v', 'v');
		ELIF('\f', 'f');
		ELIF('\r', 'r');
		ELIF('\\', '\\');
#undef ELIF
		} else if(*src < 0x20) {
			sprintf(dest, "\\x%02hhx", *src);
			dest += 4;
		} else {
			*dest++ = *src;
		}
		++src;
	}
	*dest = '\0';
}
		
int ctrlesctostr(unsigned char* dest, unsigned const char* src) {
	while(*src != '\0') {
		if(*src == '\\') {
			++src;
			if(0) { /* the optimizer will take care of this */
#define ELIF(ch, ctrl) } else if(*src == ch) { *dest = ctrl
			ELIF('a', '\a');
			ELIF('b', '\b');
			ELIF('t', '\t');
			ELIF('n', '\n');
			ELIF('v', '\v');
			ELIF('f', '\f');
			ELIF('r', '\r');
			ELIF('\\', '\\');
			} else if(*src == 'x') {
				int i;
				*dest = 0;
				for(i = 0; i < 2; ++i) {
					++src;
					if(*src >= '0' && *src <= '9')
						*dest += *src - '0';
					else if(*src >= 'A' && *src <= 'Z')
						*dest += *src - 'A' + 10;
					else if(*src >= 'a' && *src <= 'z')
						*dest += *src - 'a' + 10;
					else {
#ifdef USE_SETERROR2
						set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE);
#endif /* USE_SETERROR2 */
						return -1;
					}
					if(i == 0)
						*dest <<= 4;
				}
			} else {
#ifdef USE_SETERROR2
				set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE);
#endif /* USE_SETERROR2 */
				return -1;
			}
		} else {
			*dest = *src;
		}
		++dest;
		++src;
	}
	*dest = '\0';
	return 0;
}

#ifdef TEST_ESCAPE_C

#include <assert.h>
#include <stdio.h>
#include <string.h>

int main() {
	char test[] = "\x01\n\r\v\t\a\b\f\\\x1f\x13\x04\x05\x41";
	char buf1[100];
	char buf2[100];

	strtoctrlesc(buf1, test);
	printf("^%s$\n", buf1);
	if(ctrlesctostr(buf2, buf1) == -1)
		return 1;
	assert(strcmp(test, buf2) == 0);
	assert(ctrlesctostr(buf2, "\\qabcd") == -1);
	return 0;
}

#endif /* TEST_ESCAPE_C */
